package org.kabeja.dxf.helpers;

import org.kabeja.dxf.entity.DXFMText;
import org.kabeja.dxf.entity.DXFText;

import java.util.Stack;
import java.util.StringTokenizer;

/**
 * @author shutao
 * @since 2022/4/24 17:58
 */
public class DXFTextParser {
    public DXFTextParser() {
    }

    public static TextDocument parseDXFMText(DXFMText var0) {
        TextDocument var1 = new TextDocument();
        StringBuilder var2 = new StringBuilder();
        StringBuilder var3 = new StringBuilder();
        StyledTextParagraph var4 = new StyledTextParagraph();
        var4.setFontHeight(var0.getHeight());
        var4.setInsertPoint(var0.getInsertPoint());
        switch(var0.getAlignment()) {
            case 1:
            case 2:
            case 3:
                var4.setValign(2);
                break;
            case 4:
            case 5:
            case 6:
                var4.setValign(4);
                break;
            default:
                var4.setValign(1);
        }

        boolean var5 = false;
        boolean var6 = false;
        boolean var7 = true;
        Stack<StyledTextParagraph> var8 = new Stack<>();
        int var9 = 0;
        String var10 = var0.getText();
        char var11 = ' ';
        var10 = parseSymbols(var10);

        for(int var12 = 0; var12 < var10.length(); ++var12) {
            char var13 = var10.charAt(var12);
            switch(var13) {
                case ';':
                    if (var5) {
                        parseStyledTextParagraphSettings(var11, var3.toString(), var4);
                        var3.delete(0, var3.length());
                        var5 = false;
                        var7 = true;
                        var6 = false;
                    } else {
                        var2.append(var13);
                    }
                    break;
                case 'L':
                    if (var5 && var6) {
                        var4.setText(var2.toString());
                        var2.delete(0, var2.length());
                        var1.addStyledParagraph(var4);
                        var4 = createParagraphFromParent(var4);
                        var4.setUnderline(true);
                        var5 = false;
                        var6 = false;
                    } else if (var5) {
                        var3.append(var13);
                    } else {
                        var2.append(var13);
                    }
                    break;
                case 'O':
                    if (var5 && var6) {
                        var4.setText(var2.toString());
                        var2.delete(0, var2.length());
                        var1.addStyledParagraph(var4);
                        var4 = createParagraphFromParent(var4);
                        var4.setOverline(true);
                        var5 = false;
                        var6 = false;
                    } else if (var5) {
                        var3.append(var13);
                    } else {
                        var2.append(var13);
                    }
                    break;
                case 'P':
                    if (var5 && var6) {
                        ++var9;
                        var4.setText(var2.toString());
                        var2.delete(0, var2.length());
                        var1.addStyledParagraph(var4);
                        var4 = createParagraphFromParent(var4);
                        var5 = false;
                        var6 = false;
                        var4.setLineIndex(var9);
                        var4.setNewline(true);
                    } else if (var5) {
                        var3.append(var13);
                    } else {
                        var2.append(var13);
                    }
                    break;
                case '\\':
                    if (var5) {
                        if (!var7) {
                            parseStyledTextParagraphSettings(var11, var3.toString(), var4);
                            var3.delete(0, var3.length());
                            var6 = true;
                        } else {
                            var2.append(var13);
                            var5 = false;
                        }
                    } else {
                        var5 = true;
                        var6 = true;
                        var7 = false;
                    }
                    break;
                case 'l':
                case 'u':
                    if (var5 && var6) {
                        var4.setText(var2.toString());
                        var2.delete(0, var2.length());
                        var1.addStyledParagraph(var4);
                        var4 = createParagraphFromParent(var4);
                        var4.setUnderline(false);
                        var5 = false;
                        var6 = false;
                    } else if (var5) {
                        var3.append(var13);
                    } else {
                        var2.append(var13);
                    }
                    break;
                case 'o':
                    if (var5 && var6) {
                        var4.setText(var2.toString());
                        var2.delete(0, var2.length());
                        var1.addStyledParagraph(var4);
                        var4 = createParagraphFromParent(var4);
                        var4.setOverline(false);
                        var5 = false;
                        var6 = false;
                    } else if (var5) {
                        var3.append(var13);
                    } else {
                        var2.append(var13);
                    }
                    break;
                case '{':
                    if (var5 && var6) {
                        var2.append(var13);
                        var5 = false;
                        var6 = false;
                    } else if (var5) {
                        var3.append(var13);
                    } else if (var12 != 0) {
                        var8.add(var4);
                        var4 = new StyledTextParagraph();
                    }
                    break;
                case '}':
                    if (var5 && var6) {
                        var2.append(var13);
                        var5 = false;
                        var6 = false;
                    } else if (var5) {
                        var3.append(var13);
                    } else {
                        var1.addStyledParagraph(var4);
                        var4 = createParagraphFromParent(var4);
                        if (var8.size() > 0) {
                            var4 = var8.pop();
                        }
                    }
                    break;
                case '~':
                    if (var5) {
                        var2.append(var13);
                        var5 = false;
                        var6 = false;
                    }
                    break;
                default:
                    if (var5) {
                        if (var6) {
                            var11 = var13;
                            var6 = false;
                        } else {
                            var3.append(var13);
                        }
                    } else {
                        var2.append(var13);
                    }
            }
        }

        if (var5) {
            parseStyledTextParagraphSettings(var11, var3.toString(), var4);
        }

        if (var2.length() > 0) {
            var4.setText(var2.toString());
            var1.addStyledParagraph(var4);
        }

        if (var1.getParagraphCount() == 0) {
            var1.addStyledParagraph(var4);
        }

        return var1;
    }

    protected static StyledTextParagraph createParagraphFromParent(StyledTextParagraph var0) {
        StyledTextParagraph var1 = new StyledTextParagraph();
        var1.setValign(var0.getValign());
        var1.setBold(var0.isBold());
        var1.setFont(var0.getFont());
        var1.setItalic(var0.isItalic());
        var1.setUnderline(var0.isUnderline());
        var1.setOverline(var0.isOverline());
        var1.setWidth(var0.getWidth());
        var1.setFontHeight(var0.getFontHeight());
        var1.setInsertPoint(var0.getInsertPoint());
        return var1;
    }

    public static TextDocument parseDXFText(DXFText var0) {
        TextDocument var1 = new TextDocument();
        StringBuilder var2 = new StringBuilder();
        StyledTextParagraph var3 = new StyledTextParagraph();
        var3.setFontHeight(var0.getHeight());
        var3.setInsertPoint(var0.getAlignmentPoint());
        switch(var0.getValign()) {
            case 0:
                if (var0.getAlign() == 4) {
                    var3.setValign(4);
                } else {
                    var3.setValign(1);
                }
                break;
            case 1:
                var3.setValign(1);
                break;
            case 2:
                var3.setValign(4);
                break;
            case 3:
                var3.setValign(2);
        }

        if (var0.getAlign() == 3 || var0.getAlign() == 5) {
            double var4 = DXFUtils.distance(var0.getInsertPoint(), var0.getAlignmentPoint());
            var3.setWidth(var4);
        }

        String var10 = parseSymbols(var0.getText());
        int var5 = 0;
        boolean var7 = false;
        boolean var8 = false;

        for(int var9 = 0; var9 < var10.length(); ++var9) {
            char var6 = var10.charAt(var9);
            if (var6 == '%') {
                ++var5;
            } else if (var5 == 0) {
                var2.append(var6);
            } else if (var5 == 2) {
                switch(var6) {
                    case 'o':
                        var3.setText(var2.toString());
                        var3.setUnderline(var8);
                        var3.setOverline(var7);
                        var1.addStyledParagraph(var3);
                        var3 = createParagraphFromParent(var3);
                        var2.delete(0, var2.length());
                        var7 = !var7;
                        var3.setOverline(var7);
                        break;
                    case 'u':
                        var3.setText(var2.toString());
                        var3.setUnderline(var8);
                        var3.setOverline(var7);
                        var1.addStyledParagraph(var3);
                        var3 = createParagraphFromParent(var3);
                        var2.delete(0, var2.length());
                        var8 = !var8;
                        var3.setUnderline(var8);
                }

                var5 = 0;
            }
        }

        if (var5 == 1 || var5 == 3) {
            var2.append('%');
        }

        if (var2.length() > 0) {
            var3.setText(var2.toString());
            var1.addStyledParagraph(var3);
        }

        return var1;
    }

    public static void parseStyledTextParagraphSettings(char var0, String var1, StyledTextParagraph var2) {
        switch(var0) {
            case 'A':
                var2.setValign(Integer.parseInt(var1));
                break;
            case 'F':
                var2.setFontFile(var1.trim());
                break;
            case 'H':
                if (var1.endsWith("x")) {
                    var2.setFontHeight(var2.getFontHeight() * Double.parseDouble(var1.substring(0, var1.length() - 1)));
                } else {
                    var2.setFontHeight(Double.parseDouble(var1));
                }
                break;
            case 'Q':
                var2.setObliquiAngle(Double.parseDouble(var1));
            case 'S':
            default:
                break;
            case 'T':
                var2.setCharacterspace(Double.parseDouble(var1));
                break;
            case 'W':
                var2.setWidth(Double.parseDouble(var1));
                break;
            case 'f':
                parseFontSettings(var1.trim(), var2);
        }

    }

    public static void parseFontSettings(String var0, StyledTextParagraph var1) {
        StringTokenizer var2 = new StringTokenizer(var0, "|");
        var1.setFont(var2.nextToken());

        while(var2.hasMoreTokens()) {
            String var3 = var2.nextToken();
            char var4 = var3.charAt(0);
            int var5 = Integer.parseInt(var3.substring(1));
            switch(var4) {
                case 'b':
                    var1.setBold(var5 == 1);
                case 'c':
                case 'p':
                default:
                    break;
                case 'i':
                    var1.setItalic(var5 == 1);
            }
        }

    }

    public static String parseSymbols(String var0) {
        boolean var1 = false;
        StringBuilder var2 = new StringBuilder();
        int var3 = 0;

        for(int var5 = 0; var5 < var0.length(); ++var5) {
            char var4 = var0.charAt(var5);
            if (var4 == '%') {
                if (var3 == 2) {
                    var2.append('%');
                    var3 = 0;
                } else {
                    ++var3;
                }
            } else if (var4 == '^') {
                var1 = true;
            } else if (var1) {
                if (Character.isWhitespace(var4)) {
                    var2.append('^');
                }

                var1 = false;
            } else {
                String var6;
                if (var4 == '\\') {
                    if (var0.length() > var5 + 6 && var0.charAt(var5 + 1) == 'U' && var0.charAt(var5 + 2) == '+') {
                        var6 = var0.substring(var5 + 3, var5 + 7);
                        int var7 = Integer.parseInt(var6, 16);
                        var2.append((char)var7);
                        var5 += 6;
                    } else {
                        var2.append('\\');
                    }
                } else if (var3 == 0) {
                    var2.append(var4);
                } else if (var3 == 1) {
                    var2.append('%');
                    var3 = 0;
                } else if (var3 != 2) {
                    if (var3 == 3) {
                        var2.append('%');
                        var3 = 0;
                    }
                } else {
                    switch(var4) {
                        case 'c':
                            var2.append('∅');
                            break;
                        case 'd':
                            var2.append('°');
                            break;
                        case 'p':
                            var2.append('±');
                            break;
                        default:
                            if (Character.isDigit(var4) && var5 + 2 < var0.length()) {
                                var6 = "" + var4 + var0.charAt(var5 + 1) + var0.charAt(var5 + 2);

                                try {
                                    var4 = (char)Integer.parseInt(var6);
                                    var2.append(var4);
                                    var5 += 2;
                                } catch (NumberFormatException var8) {
                                    var2.append('?');
                                    ++var5;
                                }
                            } else {
                                var2.append("%%");
                                var2.append(var4);
                            }
                    }

                    var3 = 0;
                }
            }
        }

        if (var3 == 1 || var3 == 3) {
            var2.append('%');
        }

        return var2.toString();
    }
}
